package com.xg.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xg.frame.constant.SysConstant;
import com.xg.sys.entity.SysUser;
import com.xg.sys.entity.SysUserOrgEntity;
import com.xg.sys.service.SysUserOrgService;
import com.xg.sys.service.SysUserService;
import com.xg.sys.vo.TreeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.xg.sys.mapper.SysOrganizationMapper;
import com.xg.sys.entity.SysOrganizationEntity;
import com.xg.sys.service.SysOrganizationService;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMapper, SysOrganizationEntity> implements SysOrganizationService {
    @Autowired
    SysUserOrgService userOrgService;

    @Autowired
    SysUserService userService;

    @Override
    public void pageList(Page<SysOrganizationEntity> page, SysOrganizationEntity data) {
        QueryWrapper<SysOrganizationEntity> queryWrapper = new QueryWrapper<SysOrganizationEntity>();
        baseMapper.selectPage(page, queryWrapper);
    }

    /**
     * 机构新增保存
     * @param organization
     * @return
     */
    @Override
    public boolean saveOne(SysOrganizationEntity organization) {
        //父id默认值
        if (organization.getParentId() == null) {
            organization.setParentId(SysConstant.ROOT_PARENT_ID);
        }
        //排序默认值
        if (organization.getSort() == null) {
            organization.setSort(0);
        }
        organization.setStatus(SysConstant.STATUS_Y);
        return this.save(organization);
    }

    /**
     * 根据机构名查询
     * 新增机构时校验是否存在
     * @param name
     * @return
     */
    @Override
    public List<SysOrganizationEntity> getByName(String name) {
        List<SysOrganizationEntity> list = this.list(new QueryWrapper<SysOrganizationEntity>().lambda()
                .eq(SysOrganizationEntity::getName, name)
        );
        return list;
    }

    /**
     * 获取树形数据
     * @param enable true:查询启用的数据，false：查询所有数据
     * @param name
     * @param status
     * @return
     */
    @Override
    public List<SysOrganizationEntity> treeList(Boolean enable, String name, String status) {

        List<SysOrganizationEntity> allList = baseMapper.selectList(
                new QueryWrapper<SysOrganizationEntity>().lambda()
                        .eq(enable, SysOrganizationEntity::getStatus, SysConstant.STATUS_Y)
        );
        List<SysOrganizationEntity> compleList = null;
        if (!StringUtils.isEmpty(name)) {
            List<SysOrganizationEntity> serchList = allList.stream()
                    .filter(item -> item.getName().contains(name))
                    .collect(Collectors.toList());
            List<SysOrganizationEntity> forList= new ArrayList<>();
            forList.addAll(serchList);

            for (SysOrganizationEntity item : forList) {
                putChildrenToList(allList, serchList, item);
                putParentToList(allList, serchList, item);
            }
            compleList = serchList.stream().distinct().collect(Collectors.toList());
        }

        List<SysOrganizationEntity> finalCompleList = StringUtils.isEmpty(name) ? allList : compleList;
        List<SysOrganizationEntity> treelist = finalCompleList.stream()
                .filter(item -> item.getParentId() == 0)
                .sorted(Comparator.comparingInt(SysOrganizationEntity::getSort))
                .map(item -> putChildren(finalCompleList, item, 2))
                .collect(Collectors.toList());
        treelist.forEach(item -> item.setCatLevel(1));
        return treelist;
    }

    private void putParentToList(List<SysOrganizationEntity> allList, List<SysOrganizationEntity> serchList, SysOrganizationEntity orgEntity) {
        List<SysOrganizationEntity> collect = allList.stream().filter(item -> item.getId().equals(orgEntity.getParentId())).collect(Collectors.toList());
        if (!collect.isEmpty()) {
                serchList.add(collect.get(0));
                putParentToList(allList, serchList, collect.get(0));
        }
    }

    private void putChildrenToList(List<SysOrganizationEntity> allList, List<SysOrganizationEntity> serchList, SysOrganizationEntity orgEntity) {
        List<SysOrganizationEntity> childList = allList.stream().filter(item -> item.getParentId().equals(orgEntity.getId())).collect(Collectors.toList());
        if (!childList.isEmpty()) {
            serchList.addAll(childList);
            childList.forEach(item -> putChildrenToList(allList, serchList, item));
        }
    }

    /**
     * 更新启用状态
     * 规则：父机构状态改变，子机构随父机构一同改变
     * @param entity
     * @return
     */
    @Override
    public boolean updateTree(SysOrganizationEntity entity) {
        if (StringUtils.isEmpty(entity.getStatus())) {//不更新状态
            return this.updateById(entity);
        } else {
            List<SysOrganizationEntity> allList = baseMapper.selectList(null);
            ArrayList<SysOrganizationEntity> updateList = new ArrayList<>();
            updateList.add(entity);
            putChildrenToUpList(allList, updateList, entity);
            return this.updateBatchById(updateList);
        }
    }

    /**
     * 根据机构id分页查询当前机构所有的用户
     * 规则：如果当前机构为父id，则查询当前机构所有子机构所属用户
     * @param page
     * @param oid
     */
    @Override
    public void userPage(Page<SysUser> page, Long oid) {
        List<Long> userIdList = userOrgService.getUserIdListByOid(oid);
        if (!userIdList.isEmpty()) {
            userService.page(page,
                    new QueryWrapper<SysUser>().lambda()
                            .in(SysUser::getId, userIdList)
            );
        }
    }

    /**
     * 删除机构
     * 规则：父机构删除，所有子机构也会被删除
     * @param id
     * @return
     */
    @Override
    public boolean removeByIdForTree(Long id) {
        ArrayList<Long> delList = new ArrayList<>();
        delList.add(id);
        List<SysOrganizationEntity> allList = this.list(null);
        putIdToDelList(allList, delList, id);
        return this.removeByIds(delList);
    }

    private void putIdToDelList(List<SysOrganizationEntity> allList, ArrayList<Long> delList, Long id) {
        allList.stream().filter(item -> id.equals(item.getParentId())).forEach(item -> {
            delList.add(item.getId());
            putIdToDelList(allList, delList, item.getId());
        });
    }

    private void putChildrenToUpList(List<SysOrganizationEntity> allList, ArrayList<SysOrganizationEntity> updateList, SysOrganizationEntity entity) {
        allList.stream()
                .filter(item -> item.getParentId().equals(entity.getId()))
                .forEach(item -> {
                    SysOrganizationEntity updateEntity = new SysOrganizationEntity().setStatus(entity.getStatus()).setId(item.getId());
                    updateList.add(updateEntity);
                    putChildrenToUpList(allList, updateList, updateEntity);
                });
    }

    private SysOrganizationEntity putChildren(List<SysOrganizationEntity> allList, SysOrganizationEntity organizationEntity, Integer level) {
        List<SysOrganizationEntity> childrenList = allList.stream()
                .filter(item -> item.getParentId().equals(organizationEntity.getId()))
                .sorted(Comparator.comparingInt(SysOrganizationEntity::getSort))
                .map(item -> putChildren(allList, item, level + 1))
                .collect(Collectors.toList());
        childrenList.forEach(item -> item.setCatLevel(level));
        return organizationEntity.setChildren(childrenList);
    }

    @Override
    public List<TreeVO> treeForYkk() throws NoSuchMethodException {
        // 1.获取全部机构
        List<SysOrganizationEntity> entityList = this.list();
        return TreeVO.toTree(entityList);
    }
    @Override
    public List<TreeVO> treeForYkk(Long userId) throws NoSuchMethodException {
        // 1.获取全部机构
        List<SysOrganizationEntity> entityList = this.list();
        // 2.根据用户id获取选中机构
        List<Long> selectedIdList = userOrgService.list(
                new LambdaQueryWrapper<SysUserOrgEntity>()
                        .select(SysUserOrgEntity::getOid)
                        .eq(SysUserOrgEntity::getUserId, userId)
        ).stream()
                .map(SysUserOrgEntity::getOid)
                .collect(Collectors.toList());

        return TreeVO.toTree(entityList,selectedIdList);
    }

    @Override
    public List<SysOrganizationEntity> getByParentId(Long id) {
        return this.list(
                new LambdaQueryWrapper<SysOrganizationEntity>()
                        .eq(SysOrganizationEntity::getParentId, id)
        );
    }
}
